﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Framework.Core.Collections;
using Framework.Core.Dependency.Visitor;

namespace Framework.Core.Dependency.Domain
{
    [DataContract(IsReference = true), KnownType(typeof(Module)), KnownType(typeof(Language))]
    public class Project : Module, IVisitable<Project>
    {
        private ConcurrentHashset<Project> dependencies;
        private ConcurrentHashset<Module> modules;

        private Project(string name, string path)
            : base(name, path)
        {
            modules = new ConcurrentHashset<Module>();
            dependencies = new ConcurrentHashset<Project>();
            Files = new List<string>();
        }

        public Project(string name, string extension, string path, string assemblyName, Language language)
            : this(name, path)
        {
            Extension = extension;
            Language = language;
            AssemblyName = assemblyName;
            ComExposition = ComExposition.None;

            if (string.IsNullOrEmpty(AssemblyName))
            {
                throw new ArgumentNullException("assemblyName");
            }
        }

        [DataMember]
        public IEnumerable<Module> Modules
        {
            get { return modules; }
            set { modules = new ConcurrentHashset<Module>(value); }
        }

        [DataMember]
        public IEnumerable<Project> Dependencies
        {
            get { return dependencies; }
            set { dependencies = new ConcurrentHashset<Project>(value); }
        }

        [DataMember]
        public string AssemblyName { get; set; }

        [DataMember]
        public string Extension { get; set; }

        [DataMember]
        public IList<string> Files { get; set; }

        [DataMember]
        public Language Language { get; set; }

        [DataMember]
        public bool IsUnitTest { get; set; }

        [DataMember]
        public ComExposition ComExposition { get; set; }

        public void AddModule(Module module)
        {
            modules.Add(module);
        }

        public void AddDependency(Project dependency)
        {
            dependencies.Add(dependency);
        }

        public void Accept(IVisitor<Project> visitor)
        {
            visitor.Visit(this);
        }

        public override string ToString()
        {
            return Name;
        }
    }
}